#include "packets/em80_payload_factory.h"
#include "packets.hpp"

#include <cassert>

namespace em80_driver
{

//static function
/** Construct map on first use */
EM80PayloadFactory::FactoryMap* EM80PayloadFactory::getMap()
{
    static FactoryMap m;
    return &m;
}

//static function
void EM80PayloadFactory::registerPayloadType(int payload_id, CreateFn fn)
{
    FactoryMap *p_map(getMap());
    assert(0 == p_map->count(payload_id));      //the create method should be added at the first time
    (*p_map)[payload_id] = fn;
}







/** Helper function for when createPayload can not create a payload */
EM80PayloadBasePtr createFailed(std::string *p_what, const std::string &what)
{
    if(p_what != NULL) *p_what = what;
    return EM80PayloadBasePtr();
}

EM80PayloadBasePtr EM80PayloadFactory::createPayload(const EM80PacketPtr &packet, std::string *p_what)
{
    FactoryMap *p_map(getMap());
    FactoryMap::const_iterator search(p_map->find(*(packet->payload())));
    if(search != p_map->end())
        return search->second(packet);
    else
        return createFailed(p_what, "Unknown payload type");
}

}
